---
permalink: "/2011/3/16/Foundations-of-Programming-2-Appendix-A-jQuery-Bas/"
layout: post
date: 2011-03-16
title: "Foundations of Programming 2 - Appendix A - jQuery Basics"
tags: [ebook, ui]
---
<h2>Appendix A - jQuery Basics</h2>


<p>There's a common anecdote given by web developers, it goes something like <em>I hated JavaScript, then jQuery came along and now I love it</em>. jQuery is a JavaScript library which takes the pain out of manipulating the DOM and creating reusable JavaScript code. It isn't the only framework of its kind, but it has established itself as the most popular. Part of what makes jQuery so powerful is that it focuses on a few specific things, allowing it to be very good at those. There are two parts to mastering jQuery: first the basics of the library, then how to use the basics to build your own plugins.</p>

<p>A huge part of knowing jQuery is knowing the <code>jQuery</code> method and jQuery object. The <code>jQuery</code> method is responsible for turning a normal HTML DOM element into a jQuery object. <code>$</code> a shorthand for <code>jQuery</code>, the two are interchangeable, but most people prefer to use <code>$</code> (I know, it seems magical, but it's just a function name - JavaScript allows such characters in function names). A jQuery object is a wrapper around a DOM element which provides all type of useful manipulation and traversing methods. Let's first look at the jQuery method, and then look at jQuery objects.</p>

<h3>jQuery()</h3>

<p>In its simplest form, the <code>jQuery</code> method will turn a DOM element into a jQuery element:</p>

{% highlight javascript %}
<div id="main"></div>
<script type="text/javascript">
    var domElement = document.getElementById('main');
    var $main = $(domElement);
    //or (same thing):
    var $main = jQuery(domElement);
</script>
{% endhighlight %}

<p>(using $ as a prefix to jQuery object variables is a convention I like, if you don't, don't use it.)</p>

<p>Being able to turn a DOM element into a jQuery object is useful, as we'll see in a bit. However, the real power of the <code>jQuery</code> method (and jQuery in general) is its ability to take a CSS selector and turn that directly into a jQuery object wrapping the underlying DOM. This is nice for a couple reasons. First, you probably already know how CSS selectors work. Second, CSS selectors have proven to be quite flexible and powerful at selecting elements. Knowing this, we can drop the call to <code>getElementById</code> from the above example and simply do:</p>

{% highlight javascript %}var $main = $('#main');{% endhighlight %}

<p>Because, in CSS, you target an element by id using the <code>#ID</code> selector. Also, jQuery takes care of cross browser incompatibilities for you. It doesn't matter that IE6 (or 7) doesn't support attribute selector such as <code>input[type="text"]</code>. The jQuery selector syntax is <strong>like</strong> CSS selectors, but it uses its own engine, independent of the browser's.</p>

<h3>jQuery object</h3>

<p>Before we dig too deeply into the <code>jQuery</code> method, let's get up to speed with what it returns: a jQuery object. Actually, the method <strong>always</strong> returns an array of jQuery objects - even when you know it should just return a single value, like in the above code when we selected by id. This actually turns out to provide some nice consistency, in addition to cleaner code (no null checking), as should become evident as we move forward. A jQuery object can be manipulated via various built-in jQuery methods, 3rd party plugins, or your own custom plugins. For now, we'll stick to the built-in methods. Let's look at some examples:</p>

{% highlight javascript %}$main.text('welcome!');
$main.addClass('heading');
$main.click(function()
{
    alert('WELCOME!');
});
{% endhighlight %}

<p>As a general rule, a jQuery method (built-in or not) returns the array of jQuery object being manipulated. This means that method calls are meant to be chained, so the above can be rewritten as:</p>

{% highlight javascript %}$main.text('welcome').addClass('heading').click(function()
{
    alert('WELCOME!');
});
{% endhighlight %}

<p>When dealing with an array of jQuery objects with more than 1 element, all elements items are affected. When dealing with an empty element, nothing happens.</p>

<p>The built-in jQuery method can be broken down into specific categories of behavior. Let's look at a few of the methods in each category.</p>

<h4>Attribute Methods</h4>

<p>Attribute methods let you manipulate the HTML attributes of the DOM elements your jQuery array wraps. We already saw the <code>text</code> and <code>addClass</code> methods above, but there's also the more generic <code>attr</code> and <code>css</code> methods, as well as a handful of others:</p>

{% highlight javascript %}$links.attr('href', '#')
    .text('DOH!')
    .removeClass('active');
{% endhighlight %}

<p>Some jQuery attribute methods have a fairly unique property: they don't return the original array of jQuery objects. Luckily, this is actually pretty intuitive. You see, most of them can be used for both setting a value (like we see above) or reading a value. When reading a value, logically, the value itself is returned (and it's only the first value of the array):</p>

{% highlight javascript %}var firstLink = $('a').attr('href');
var tablesBorder = $('table.list').css('border');
var username = $('input[name="username"]).val();
{% endhighlight %}

<h4>Traversing</h4>

<p>jQuery has an extensive number of traversal methods which let you get to jQuery objects starting from other jQuery objects. The simplest example is the <code>children</code> method:</p>

{% highlight html %}<ul id="menu">
    <li><a href="#" class="current">home</a></li>
    <li><a href="#">login</a></li>
    <li><a href="#>register</a></li>
</ul>

<script type="text/javascript">
    var $menuItems = $('ul li');
    //or
    var $menuItems = $('ul').children();
</script>
{% endhighlight %}

<p>The <code>find</code> method is similar to <code>children</code> except it looks at the children of children (all the way down). So, to find the current menu item, we could do any of the following:</p>

{% highlight javascript %}var $current = $('.current'); //might return more than we want
var $current = $('#menu .current'); //just a normal css selector
var $current = $('#menu').find('.current');
var $current = $('#menu').children().children('.current');
var $current = $('#menu a').filter('.current');
{% endhighlight %}

<p>Here we see both <code>find</code> and <code>filter</code> at play (as well as an overload of <code>children</code> which takes a selector). All of this is just the tip of the iceberg of both what's built in and what's possible. Here are two other, very common examples:</p>

{% highlight javascript %}$current.sibling().addClass('notActive');
var $menu = $current.closest('ul');
{% endhighlight %}

<p><code>sibling</code> is self-explanatory. <code>closest</code> is the opposite of <code>find</code> going <strong>up</strong> the hierarchy looking for a match. There's also <code>parent</code> which finds the immediate parent, but if you find yourself chaining calls to <code>parent</code> it'll almost always be better to use <code>closest</code>:</p>

{% highlight javascript %}var $menu = $current.closest('ul'); //much better than:
var $menu = $current.parent().parent();
{% endhighlight %}

<p>It's possible that you are put off by the seemingly limitless way you can target specific elements. The truth is that in real code and with a experience, a best way is generally obvious.</p>

<h4>Manipulation</h4>

<p>The manipulation method give us great control over changing our elements. There's some overlap between these and the attribute methods, so we'll focus on moving things around:</p>

{% highlight javascript %}$('#menu').clone().appendTo($('body'));
$('.current').remove();
$('#menu a).wrapAll('<p></p>');
{% endhighlight %}

<p>These kind of methods are particularly useful when writing plugins and aren't as useful as standalone calls.</p>

<h4>Events</h4>

<p>Event methods let you cleanly hook up events (again, in a cross platform manner) to jQuery objects. For example, not all browsers support the CSS :hover pseudo-selector on all types of elements, but with jQuery we can use the <code>mouseenter</code> and <code>mouseleave</code> events to accomplish something similar (there's also a <code>hover</code> event, but I find it somewhat cumbersome):</p>

{% highlight javascript %}$('tr').mouseenter(function()
{
    $(this).addClass('hover');
}).mouseleave(function()
{
    $(this).removeClass('hover');
}).click(function()
{
    alert('Your clicked the row at index: ' + $(this).index());
});
{% endhighlight %}

<p>Woah, what's all <code>$(this)</code> about? <code>this</code> is the one tricky thing you'll have to really think about if you want to learn jQuery - it's where normal JavaScript bleeds into jQuery. <code>this</code> is a special keyword in JavaScript which has special contextual meaning - change the context, and chances are <code>this</code> will mean something else (when you think about it, this is true of C# as well). When JavaScript raises an event, <code>this</code> becomes the DOM element on which the event was raised. In our example above, <code>this</code> is the table row (tr) which caused either a mouse enter or mouse leave event. As we saw in our very first jQuery example, a DOM element can be turned into a jQuery element by using the <code>jQuery</code> method. So, in short, <code>$(this)</code> is turning the DOM element represented by <code>this</code> (which in the case of events is the DOM element which caused the event) into a jQuery object.</p>

<h4>document.ready</h4>

<p>There's one special event that we probably should have talked about by now. All of our jQuery examples have placed our JavaScript code directly in a <script> tag. This will work, however it can cause some odd flickering as the page first loads and displays the initial state, and then your jQuery code changes it. Ideally, we want to apply our manipulation as soon as the elements are loaded, but before they are displayed. In standard HTML, there's a <code>readyStateChanged</code> event which can be used for just this type of thing. jQuery provides a handy way to leverage it:</p>

{% highlight javascript %}$(document).ready(function()
{
    //all your code should go here
});
{% endhighlight %}

<p>If you've been following along, the above should be a pretty clear 2 step process. First, we turn the <code>document</code> element into a jQuery object (<code>$(document)</code>), next we hook into its <code>ready</code> event.</p>

<h3>Bringing It Together</h3>

<p>When you put all the pieces together, you end up with the capability to write some pretty nice JavaScript code with a minimum amount of effort. For example, let's use what we've learned to build some basic tabs (this is an ideal candidate for a plugin, but let's not worry about that for now):</p>

{% highlight html %}<style>
    a.active{font-weight:bold;}
</style>

<ul class="tabs">
    <li><a href="#main">main</a></li>
    <li><a href="#about">about</a></li>
    <li><a href="#download">download</a></li>
</ul>

<div id="main" class="panel">This is the main panel</div>
<div id="about" class="panel">this is the about panel</div>
<div id="download" class="panel">this is the download panel</div>

<script type="text/javascript">
$(document).ready(function()
{
    var $panels = $('.panel').hide();

    var $links = $('.tabs a');
    $links.click(function()
    {
        var $link = $(this);
        $links.removeClass('active');
        $link.addClass('active');

        $panels.hide();
        $panels.filter($link.attr('href')).show();
    }).filter(':first').click();
});
</script>
{% endhighlight %}

<p>There isn't too too much going on here. The first thing we do is get a reference to and hide all of the panels. Next we hook into the click event for each of our menu's links. Within this event we do a few things, but it all starts by getting a reference to the clicked linked. We remove the <code>active</code> class from any link and hide all the panels (there are a lot of ways we could have done this, but this is probably the simplest). The last step within the click event is to show the corresponding panel (notice that link's href conveniently references the appropriate panel's id). There's one last step, which is easy to miss, and that is we trigger a <code>click</code> on the first link (we'll look at the <code>:first</code> selector in the next section). This last step, accomplished via the useful <code>filter</code> method, causes our page to initialize to a reasonable default.</p>

<h3>In This Chapter</h3>

<p>We've only covered a small part of jQuery's built-in capabilities. There are ajax methods and effect methods we didn't look at, as well as many more selectors, traversal, manipulation and events. What's important to take away from this chapter is that the <code>jQuery</code> method (or <code>$</code>) takes a CSS selector (or less frequently an existing DOM object) and returns an array of jQuery objects. These jQuery objects have a number of built-in methods which aren't only valuable by themselves, but serve as the foundation for writing your own methods that can encompass a specific behavior (which is what the next chapter is all about).</p>
